
#pragma once

// Team Nine Sixes
// EggNine

#include "gl/glew.h"
#include "mymath.h"
#include "ublocks.h"
#include "technique.h"
#include "mesh.h"

// TODO Remove this header from here, since it gets bound to PCH
#include "cmnBlocks.h"

#include <vector>
#include <queue>

using namespace std;

namespace EggNine {

class Scene {
    vec4                    m_qRot;
    vec4                    m_qRotTheta;
    vec4                    m_Trans;
    vec4                    m_lightsPos[MAX_LIGHTS];
    LightsBlock             m_lights;
    CameraBlock             m_matrices;
    CameraBlock             m_inverseMatrices;
    ModelBlock              m_modelStuff;
    MaterialBlock           m_material;
    WaveSimBlock            m_waveParams;
    
    map<MeshPresentMethod, vector<PresentableMesh*>>      m_meshes;
    map<MeshSimulateMethod, vector<SimulateableMesh*>>     m_simMeshes;
    vector<IMesh*>                              m_meshList;
    map<MeshPresentMethod, IProgram*>           m_drawEffects;
    map<MeshSimulateMethod, IProgram*>          m_simulateEffects;
    
    GLsizei                 m_width, m_height;
    UniformMap              m_uniformBlocks;

    ProgramsMap             m_effectMap;

    float                   m_near,m_far,m_fov,m_ar;
    float                   m_phi,m_theta;
    bool                    m_lockToY;
    //int i[5000];

    void CreateCameraMatrix();
public:
    Scene();
    ~Scene();
    void* operator new(size_t size);
    void operator delete(void* addr);

    void Reshape(int width, int height);
    void Translate(float dx, float dy, float dz);
    void Scale(float magnitude);
    void RotateAroundAxis(float x, float y, float z, float angle);
    void RotateViewBy(float dphi, float dtheta);

    void Render(float dt);
    void AttachMesh(IMesh* mesh);

    void SelectEvent(int x, int y);

    void AttachUniformBlock(const UniformBlock* uBlock);
};

} // EggNine
